package com.info33.platform.common.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metric;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * @author debj
 * @version 1.0
 * @date 2021/6/17 14:03
 */
@Component
public class RedisGeo {

    private static final String ON_LINE_USER_LOCATION = "onLineUserLocation";

    private final StringRedisTemplate redisTemplate;

    @Autowired
    public RedisGeo(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 添加位置信息
     *
     * @param longitude 经度
     * @param latitude  纬度
     * @param member    成员名称
     */
    public void add(double longitude, double latitude, String member) {
        redisTemplate.opsForGeo().add(ON_LINE_USER_LOCATION, new RedisGeoCommands.GeoLocation<>(member, new Point(longitude, latitude)));
    }

    /**
     * 计算两个成员之间的距离
     *
     * @param member  成员名称 1
     * @param member2 成员名称 2
     */
    public Distance pos(String member, String member2, Metric metric) {
        try {
            return redisTemplate.opsForGeo().distance(ON_LINE_USER_LOCATION, member, member2, metric);
        } catch (RedisSystemException e) {
            return new Distance(-1.0);
        }
    }

    /**
     * 清除
     *
     * @param member 成员名称
     */
    public void remove(String member) {
        redisTemplate.opsForGeo().remove(ON_LINE_USER_LOCATION, member);
    }

    /**
     * 获取某键下，某个成员的位置信息
     *
     * @param member 成员
     * @return point
     */
    public Point get(String member) {
        List<Point> position = redisTemplate.opsForGeo().position(ON_LINE_USER_LOCATION, member);
        if (!ObjectUtils.isEmpty(position) && !position.isEmpty()) {
            return position.get(0);
        }
        return null;
    }

}
